/**
 * @file 通用右键菜单（主进程）IPC处理与构建, 菜单数据由渲染进程传入
 * 与 srcRenderer/utils/contextMenuHelper.ts 配合使用
 */
import type { MenuItemConstructorOptions, NativeImage, WebContents } from 'electron'
import type { ContextMenuItem, MenuDisplayOptions } from '~shared/types/context-menu'
import { BrowserWindow, ipcMain, Menu, MenuItem, nativeImage } from 'electron'
import { contextMenuTopic } from '~shared/ipc-topic'

const MENU_DEFAULTS = {
  TYPE: 'normal' as const,
  ENABLED: true,
  VISIBLE: true
} as const

function processMenuIcon(iconString: string): string | NativeImage | null {
  try {
    if (iconString.startsWith('data:')) {
      const nativeImg = nativeImage.createFromDataURL(iconString)
      return nativeImg && !nativeImg.isEmpty() ? nativeImg : null
    } else {
      return iconString
    }
  } catch (error) {
    console.warn('处理菜单图标失败:', error)
    return null
  }
}

function buildMenuItemOptions(
  item: ContextMenuItem,
  callbackId: string,
  index: number,
  webContents: WebContents
): MenuItemConstructorOptions {
  const options: MenuItemConstructorOptions = {
    label: item.label || '',
    type: item.type || MENU_DEFAULTS.TYPE,
    enabled: item.enabled !== false,
    visible: item.visible !== false,
    checked: item.checked
  }

  if (item.icon) {
    const icon = processMenuIcon(item.icon)
    if (icon) options.icon = icon
  }

  if (item.submenu && item.submenu.length > 0) {
    options.submenu = createGenericContextMenu(item.submenu, `${callbackId}-${index}`, webContents)
  } else {
    options.click = () => {
      const callbackEventName = `${contextMenuTopic.callback}-${callbackId}-${index}`
      webContents.send(callbackEventName)
    }
  }
  return options
}

export function createGenericContextMenu(
  menuItems: ContextMenuItem[],
  callbackId: string,
  webContents: WebContents
): Menu {
  const menu = new Menu()
  for (const [index, item] of menuItems.entries()) {
    if (item.type === 'separator') {
      menu.append(new MenuItem({ type: 'separator' }))
      continue
    }
    const menuItemOptions = buildMenuItemOptions(item, callbackId, index, webContents)
    menu.append(new MenuItem(menuItemOptions))
  }
  return menu
}

function showMenuAtPosition(
  menu: Menu,
  webContents: WebContents,
  options?: MenuDisplayOptions
): void {
  if (options?.x !== undefined && options?.y !== undefined) {
    const window = BrowserWindow.fromWebContents(webContents)
    if (window) {
      menu.popup({ window, x: options.x, y: options.y })
    } else {
      menu.popup({ x: options.x, y: options.y })
    }
  } else {
    menu.popup()
  }
}

export function setupGenericContextMenuHandlers(): void {
  ipcMain.on(
    contextMenuTopic.show,
    (
      event,
      data: { menuItems: ContextMenuItem[]; callbackId: string; options?: MenuDisplayOptions }
    ) => {
      try {
        const { menuItems, callbackId, options } = data
        const webContents = event.sender
        const menu = createGenericContextMenu(menuItems, callbackId, webContents)
        menu.once('menu-will-close', () => {
          const closeEventName = `${contextMenuTopic.closed}-${callbackId}`
          webContents.send(closeEventName)
        })
        showMenuAtPosition(menu, webContents, options)
      } catch (error) {
        console.error('显示通用右键菜单时发生错误:', error)
      }
    }
  )
}
